﻿// Copyright (C) Microsoft Corporation. All Rights Reserved.
// This code released under the terms of the
// Microsoft Limited Public License (Ms-LPL).

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;

using Microsoft.VisualStudio.IntelliTrace;

namespace Microsoft.VisualStudio.Samples
{
	internal class ThreadChainFormatter : EventChainFormatter
	{
        public ThreadChainFormatter(IntelliTraceProcess process)
            : base(process)
		{
            handlers = new List<ThreadChainHandler>();
        }

        public IntelliTraceThread Thread { get; set; }
		private IList<ThreadChainHandler> handlers;

        public override void FireEvents()
        {
            if (handlers.Count > 0) base.FireEvents();
        }

		protected override void FireEvent(IntelliTraceEvent ev)
		{
                foreach (ThreadChainHandler handler in handlers)
                {
                    handler.Process = Process;
                    if (ev.GetType() == typeof(MethodEnterEvent) || ev.GetType().IsSubclassOf(typeof(MethodEnterEvent)))
                    {
                        handler.MethodEnterEvent(ev);
                    }
                    else if (ev.GetType() == typeof(MethodExitEvent) || ev.GetType().IsSubclassOf(typeof(MethodExitEvent)))
                    {
                        handler.MethodExitEvent(ev);
                    }
                    else if (ev.GetType() == typeof(CallSiteEvent) || ev.GetType().IsSubclassOf(typeof(CallSiteEvent)))
                    {
                        handler.CallSiteEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionThrownEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionThrownEvent)))
                    {
                        handler.ExceptionThrownEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionSearchFunctionEnterEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionSearchFunctionEnterEvent)))
                    {
                        handler.ExceptionSearchFunctionEnterEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionSearchFunctionExitEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionSearchFunctionExitEvent)))
                    {
                        handler.ExceptionSearchFunctionExitEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionSearchFilterEnterEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionSearchFilterEnterEvent)))
                    {
                        handler.ExceptionSearchFilterEnterEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionSearchFilterExitEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionSearchFilterExitEvent)))
                    {
                        handler.ExceptionSearchFilterExitEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionSearchCatchFoundEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionSearchCatchFoundEvent)))
                    {
                        handler.ExceptionSearchCatchFoundEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionUnwindFunctionEnterEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionUnwindFunctionEnterEvent)))
                    {
                        handler.ExceptionUnwindFunctionEnterEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionUnwindFunctionExitEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionUnwindFunctionExitEvent)))
                    {
                        handler.ExceptionUnwindFunctionExitEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionUnwindFinallyEnterEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionUnwindFinallyEnterEvent)))
                    {
                        handler.ExceptionUnwindFinallyEnterEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionUnwindFinallyExitEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionUnwindFinallyExitEvent)))
                    {
                        handler.ExceptionUnwindFinallyExitEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionCatchEnterEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionCatchEnterEvent)))
                    {
                        handler.ExceptionCatchEnterEvent(ev);
                    }
                    else if (ev.GetType() == typeof(ExceptionCatchExitEvent) || ev.GetType().IsSubclassOf(typeof(ExceptionCatchExitEvent)))
                    {
                        handler.ExceptionCatchExitEvent(ev);
                    }
                }
        }



        protected override StreamChain getStreamChain()
        {
            return Thread.CreateThreadChain<ThreadStreamChain>();
        }

        public void AddHandler(ThreadChainHandler handler)
        {
            handlers.Add(handler);
        }

    }
}
